#include <QtGui>
#include <QtWebKit/QWebFrame>
#include <iostream>

#include "MainWindow.h"
#include "WebBrowser.h"
#include "Bookmarks.h"
#include "Translate.h"
#include "TextWindow.h"
#include "Log.h"

MainWindow::MainWindow(const QString& windowName, QWidget *parent) : QMainWindow(parent)
{
  slot_loadTrustedHost();           // load trusted hosts first
  Translator::loadDictionaries();   // then the dictionaries
	this->setWindowTitle(windowName);
	createWidgets();
	createActions();
	createToolbar();
	createLayout();
	connectSignals();

	m_tab->currentWidget()->setFocus();
	m_bookmark = new Bookmarks;
	slot_loadBookmark();

  m_textWindow = new TextWindow("Text view", this);
  //m_textWindow->showMinimized();
  //m_textWindow->hide();
  //m_textWindow->close();

	Log::m_log << "Done initializing main window\n";
}

MainWindow::~MainWindow()
{
	delete m_bookmark;
  m_textWindow->deleteLater();
}

void MainWindow::createWidgets()
{
	this->m_edAddress = new QLineEdit;
	this->m_chkAutoTranslate = new QCheckBox("Auto");
	this->m_tab = new QTabWidget;
	m_tab->setTabsClosable(true);
	slot_newTab();
	this->m_lblStatus = new QLabel;
  this->m_tbBookmark = new QToolBar("Bookmarks");
}

void MainWindow::createActions() 
{
	this->m_actNewTab = new QAction("+++", this);
	this->m_actGo = new QAction("Go", this);
	this->m_actSaveBookmark = new QAction("Save Bookmarks", this);
	this->m_actLoadBookmark = new QAction("Load Bookmarks", this);
	this->m_actRemoveBookmark = new QAction("Remove Bookmarks", this);
	this->m_actBookmark = new QAction("Bookmark this page", this);
	this->m_actTranslate = new QAction("Translate", this);
	this->m_actTranslateText = new QAction("Translate Text", this);

	this->m_actBackward = new QAction("<--", this);
	this->m_actForward = new QAction("-->", this);
  this->m_actCopyText = new QAction("Copy", this);
  this->m_actSearchText = new QAction("Search", this);
}

void MainWindow::createToolbar() 
{
	this->m_tbFile = addToolBar("File");
	m_tbFile->addAction(m_actNewTab);
	m_tbFile->addAction(m_actTranslate);
	m_tbFile->addWidget(m_chkAutoTranslate);

	this->m_tbAddress = addToolBar("Address");
	m_tbAddress->addWidget(m_edAddress);
	m_tbAddress->addAction(m_actGo);
	m_tbAddress->addAction(m_actSaveBookmark);
	m_tbAddress->addAction(m_actLoadBookmark);
	m_tbAddress->addAction(m_actRemoveBookmark);
	m_tbAddress->addAction(m_actBookmark);

	this->addToolBarBreak();
  this->m_tbBrowserAction = addToolBar("Browser Action");
	m_tbBrowserAction->addAction(m_actBackward);
	m_tbBrowserAction->addAction(m_actForward);
	m_tbBrowserAction->addAction(m_actCopyText);
	m_tbBrowserAction->addAction(m_actSearchText);
	m_tbBrowserAction->addAction(m_actTranslateText);
}

void MainWindow::createLayout()
{
  QWidget *ctrWidget = new QWidget;
  QVBoxLayout *layout = new QVBoxLayout;
  layout->addWidget(m_tbBookmark);
  layout->addWidget(m_tab);
  layout->addWidget(m_lblStatus);
  ctrWidget->setLayout(layout);
	this->setCentralWidget(ctrWidget);
	this->showMaximized();
	//m_browser->load(QUrl::fromUserInput("google.com"));
}

void MainWindow::connectSignals()
{
	connect(m_actNewTab, SIGNAL(triggered()), this, SLOT(slot_newTab()));
	connect(m_actTranslate, SIGNAL(triggered()), this, SLOT(slot_translate()));
	connect(m_actTranslateText, SIGNAL(triggered()), this, SLOT(slot_translateText()));

	connect(m_edAddress, SIGNAL(returnPressed()), this, SLOT(slot_addressEntered()));
	connect(m_actGo, SIGNAL(triggered()), this, SLOT(slot_addressEntered()));

  connect(m_actBackward, SIGNAL(triggered()), this, SLOT(slot_backward()));
	connect(m_actForward, SIGNAL(triggered()), this, SLOT(slot_forward()));
  connect(m_actCopyText, SIGNAL(triggered()), this, SLOT(slot_copyText()));
  connect(m_actSearchText, SIGNAL(triggered()), this, SLOT(slot_searchText()));
	
  connect(m_actSaveBookmark, SIGNAL(triggered()), this, SLOT(slot_saveBookmark()));
	connect(m_actLoadBookmark, SIGNAL(triggered()), this, SLOT(slot_loadBookmark()));
	connect(m_actRemoveBookmark, SIGNAL(triggered()), this, SLOT(slot_removeBookmark()));
	connect(m_actBookmark, SIGNAL(triggered()), this, SLOT(slot_bookmark()));

	connect(m_tab, SIGNAL(currentChanged(int)), this, SLOT(slot_updateAddress()));
  connect(m_tab, SIGNAL(tabCloseRequested(int)), this, SLOT(slot_tabCloseRequested(int)));
}

// =========== Helper functions ================
WebBrowser* MainWindow::currentBrowser() 
{ 
	return static_cast<WebBrowser*> (m_tab->currentWidget()); 
}

WebBrowser* MainWindow::addBrowser(bool original, const QString& url)
{
	WebBrowser *browser = new WebBrowser(this);
	browser->m_original = original;
  if (original) {
    addTrustedHost(QUrl::fromUserInput(url).host());
	//WebBrowser *tr_browser = new WebBrowser;
	//m_browserMap[browser] = tr_browser;
	//m_browserMap[tr_browser] = browser;
	  loadUrl(browser, QUrl::fromUserInput(url));
  }
	int index = m_tab->addTab(browser, "");
	connect(browser, SIGNAL(urlChanged(const QUrl&)), this, SLOT(slot_urlChanged(const QUrl&)));
	connect(browser, SIGNAL(titleChanged(const QString&)), this, SLOT(slot_titleChanged(const QString&)));
	connect(browser, SIGNAL(loadProgress(int)), this, SLOT(slot_loadProgress(int)));
	connect(browser->page(), SIGNAL(linkHovered ( const QString &, const QString &, const QString &)),
          this, SLOT(slot_linkHovered ( const QString &, const QString &, const QString &)));
	//connect(browser, SIGNAL(loadFinished(bool)), this, SLOT(slot_loadFinished(bool)));
  //	connect(browser, SIGNAL(linkClicked(const QUrl&)), this, SLOT(slot_linkClicked(const QUrl&)));
	//connect(tr_browser, SIGNAL(urlChanged(const QUrl&)), this, SLOT(slot_urlChanged(const QUrl&)));
	//connect(tr_browser, SIGNAL(titleChanged(const QString&)), this, SLOT(slot_titleChanged(const QString&)));
	//connect(tr_browser, SIGNAL(loadFinished(bool)), this, SLOT(slot_loadFinished(bool)));
	return browser;
}

void MainWindow::addTrustedHost(const QString& host)
{
  if (!m_trustedHost.contains(host)) {
    Log::m_log << "Add trusted host " << host << "\n";
    m_trustedHost << host;
    slot_saveTrustedHost();
  }
}

void MainWindow::loadUrl(WebBrowser *s, const QUrl& url)
{
  s->load(url);
  if (this->m_chkAutoTranslate->isChecked())
    connect(s, SIGNAL(loadFinished(bool)), this, SLOT(slot_loadFinished(bool)));
//  if (!this->m_chkAutoTranslate->isChecked())
//    s->load(url);
//  else
//    s->loadAndTranslate(url);
}

// ================ KEY EVENT ==============
void MainWindow::keyPressEvent(QKeyEvent *e) 
{
  Log::m_log << "Key pressed: key = " << dec << e->key()  << " modifier = 0x" << hex << e->modifiers() << dec << endl;
  WebBrowser *s = currentBrowser();
  if (e->key() == Qt::Key_T && e->modifiers() == Qt::ControlModifier)         // Ctrl+T new tab
    slot_newTab();
  else if (e->key() == Qt::Key_C && e->modifiers() == Qt::ControlModifier)    // Ctrl+C copy text
    slot_copyText();
  else if (e->key() == Qt::Key_R && e->modifiers() == Qt::ControlModifier)    // Ctrl+R translate
    slot_translate();
  else if (e->key() == Qt::Key_Y && e->modifiers() == Qt::ControlModifier)    // Ctrl+R translate
    slot_translateText();
  else if (e->key() == Qt::Key_A && e->modifiers() == Qt::ControlModifier)    // Ctrl+A select all
    browserAction(QWebPage::SelectAll);
  else if (e->key() == Qt::Key_H && e->modifiers() == Qt::ControlModifier) {   // Ctrl+H follow current link under mouse
    if (m_currentUrl.isValid())
      this->addBrowser(true, m_currentUrl.toString());
  }
  else if (e->key() == Qt::Key_PageUp && e->modifiers() == Qt::ControlModifier && m_tab->count() > 0) { // Ctrl+PgUp prev tab
    int index = m_tab->currentIndex()-1;
    if (index < 0) index = m_tab->count()-1;
    m_tab->setCurrentIndex(index);
  }
  else if (e->key() == Qt::Key_W && e->modifiers() == Qt::ControlModifier && s) {  // Ctrl+W  close tab
    int index = m_tab->currentIndex();
    m_tab->removeTab(index);
    s->deleteLater();
  }
  else if (e->key() == Qt::Key_G && e->modifiers() == Qt::ControlModifier) {  // Ctrl+G go to link (open new tab)
    this->browserAction(QWebPage::CopyLinkToClipboard);
    QString url = QApplication::clipboard()->text();
    this->addBrowser(true, url);
  }
  else if (e->key() == Qt::Key_Plus && e->modifiers() & Qt::ControlModifier  && s) {        // Ctrl+T new tab
    Log::m_log << "KeyPlus " << dec << Qt::Key_Plus << endl;
    int size = s->page()->settings()->fontSize(QWebSettings::MinimumFontSize);
    size = (size < 20) ? 20 : size+2;
    s->page()->settings()->setFontSize(QWebSettings::MinimumFontSize, size);
  }
  else if (e->key() == Qt::Key_Minus && e->modifiers() & Qt::ControlModifier  && s) {        // Ctrl+T new tab
    Log::m_log << "KeyMinus = " << dec << Qt::Key_Minus << endl;
    int size = s->page()->settings()->fontSize(QWebSettings::MinimumFontSize);
    size = (size < 22) ? 20 : size-2;
    s->page()->settings()->setFontSize(QWebSettings::MinimumFontSize, size);
  }
  else if (e->key() == Qt::Key_S && e->modifiers() == Qt::ControlModifier) {  // save dictionaries
    for (int i = 0; i < Translator::m_dic.size(); i++) 
      Translator::m_dic[i].save(QString::number(i) + ".txt");
  }
  else if (e->key() == Qt::Key_Q && e->modifiers() == Qt::ControlModifier && s) {  // Ctrl+Q open text view
      //QString html = s->page()->mainFrame()->toHtml();
      //Tags tags;
      //Translator::parseHtml(html, tags);
//      QString text = QApplication::clipboard()->text();
    QString text = s->selectedText();
    text.replace("&nbsp;", " ");
    text.replace("<br/>", "\n\n");
    m_textWindow->setOriginalText(text);
    m_textWindow->show();
    //m_textWindow->showMaximized();
    m_textWindow->setFocus();
    Log::m_log << "Open text window" << endl;
  }
  else if (e->key() == Qt::Key_PageDown && e->modifiers() == Qt::ControlModifier && m_tab->count() > 0) { // Ctrl+PgDown next tab
    int index = m_tab->currentIndex()+1;
    if (index >= m_tab->count()) index = 0;
    m_tab->setCurrentIndex(index);
  }
  else if (e->key() == Qt::Key_F && e->modifiers() == Qt::ControlModifier && m_tab->count() > 0) {   // Ctrl+F
    WebBrowser *browser = currentBrowser();
    if (browser) {
      bool ok;
      QString text = QInputDialog::getText(this, "Find ...", "Enter text to find", QLineEdit::Normal, m_lastFindText, &ok);
      if (ok) {
        if (text != m_lastFindText) {
          browser->findText("", QWebPage::HighlightAllOccurrences);  // clear highlighted text        
          browser->findText(text, QWebPage::HighlightAllOccurrences);
        }
        browser->findText(text);
        m_lastFindText = text;
      }
    }
  }
  else
    QMainWindow::keyPressEvent(e);
}
